/*******************************************************************************************
 * File:   board_init.c
 * Description: 主板初始化
 *
 *  SWD+UART1; 短扩展口EXP2:PA2/PA3->USART2 230400 激光雷达; TYPEC左USB-COM：UART3;
 *  TYPEC右USB-DEBUG ;蓝牙PC10/11:UART4;长扩展口EXP1: PD2/PC12:UART5 连接遥控
 *  I2C:PB6-SCL  PB7-SDA
 *
 *
 * freeRtos  独立线程运行  先 Board_Init()  后 Motor_Init()
 * 1. BuzzerBeep()  蜂鸣器鸣叫
 * 2. LedGreen_Blink(3)  LED3闪烁3次
 * 3. 重定向printf到UART,方便调试; 开启printf()浮点数支持
 * 4.
 * 5. 启动HAL_ADC_Start(&hadc1); 启动ADC 获取电压使能
 * 6. OLED 使能
 * 7. UART5 连接遥控器,开启DMA中断读取遥控器数据（dma callback 接收中断回调）
 *********************************************************************************************/

#include "app.h"

#include "bsp_voice.h"

asm(".global _printf_float");  // 使能printf浮点数支持

uint8_t uart5_rx_buffer[32] = {0};
SBUS_HandleTypeDef hsbus1 = {0};  /// 声明一个sbus解析器对象

#define MOTOR_HCAN_PTR &hcan1

/********************************************************************* */
void APP_Task01_Init() {
    osDelay(100);

    HAL_UARTEx_ReceiveToIdle_DMA(&huart5, uart5_rx_buffer, sizeof(uart5_rx_buffer));  // 启动DMA接收,用来接收遥控器数据
    __HAL_DMA_DISABLE_IT(huart5.hdmarx, DMA_IT_HT);                                   // 关闭DMA接收缓冲区半满中断

    // 初始化移动检测端口
    BSP_MoveDetect_Init();  // 移动检测

    osDelay(100);
    BuzzerBeep(250, 3);
    LedRedBlink(150, 3);
    LedGreenBlink(150, 3);

    // 初始化电压传感器
    BSP_Volte_Init();
    // 初始化OLED
    BSP_OLED_Init();
    BSP_OLED_Welcome();
    // 电机初始化
    BSP_MotorControl_Init();
    BSP_Wheel_Detect_Init();

    char msg[] = "大家好，我是刘小帅，我是一台超级机器人，来看我表演喽。";
    char send[128] = {0};
    // 发送语音
    uint16_t len = generate_voice_command(send, msg, strlen(msg));
    // 打印协议头用于调试
    printf("HEAD:");
    for (int i = 0; i < 5; i++) {
        printf("%02X ", (uint8_t)send[i]);
    }
    printf("\n");
    HAL_UART_Transmit(&huart3, (uint8_t*)send, len,1000);  // DEBUG

    BSP_Lidar_Init();
}

/***************************************************** */
void APP_Task01_Loop() {
    osDelay(3000);
    // 电机运行
    for (;;) {
        BSP_MotorControl_Loop(&hsbus1, &ld06_frame);  // 传入的标准RBUS句柄
        osDelay(10);
    }
}
/***************************************************** */
void APP_Task02_Init() {
    //
}

void APP_Task02_Loop() {
    osDelay(3000);
    for (;;) {
        // 开启雷达
        // BSP_Lidar_Loop();  // 决策
        BSP_MoveDetect_Loop();  // 移动检测
        BSP_OLED_ShowVolte();   // 显示电压
        osDelay(100);
    }
}
/****************************************************** */
void APP_Task03_Init() {
    osDelay(3000);
    // 初始化CAN驱动 传入CAN句柄
    int8_t return_value = BSP_CAN_Init(MOTOR_HCAN_PTR);
    if (return_value == 0) {
        printf("CAN init cuccessful\r");
    } else {
        printf("CAN init error code:%d.\r", return_value);
    }

    // AX_MPU6050_Start();
}

void APP_Task03_Loop() {
    osDelay(3000);
    while (1) {
        // 处理CAN通信
        //    BSP_CAN_Loop(&hcan1);
        BSP_Wheel_Detect_Loop();  // 轮式检测

        osDelay(100);
    }
}

/****************************************************** */

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size) {
    static uint32_t count = 0;
    static uint32_t error = 0;
    // char msg[64] = {};

    if (huart->Instance == UART5)  // UART5接收中断处理函数
    {
        if (SBUS_Update(&hsbus1, uart5_rx_buffer, Size)) {
            count++;
            //  sprintf(msg, "s:%2d,c:%5ld,e:%2ld\n", Size, count, error);
            //  AX_OLED_Disp16Str(0, 5, (u_int8_t*)msg, 0);  // OLED指定位置显示ASCII字符串（8X16）

            // HAL_UART_Transmit_IT(&huart1, (uint8_t*)msg, strlen(msg));//DEBUG
            //   OLED_ShowHexArray(0, 4, (uint8_t *)&(sbus_parser.raw_data), Size);
        } else {
            error++;

            // sprintf(msg, "s:%d, c:%ld, e:%ld", Size, count, error);
            //  OLED_ShowString(0, 2, msg);
        }

        HAL_UARTEx_ReceiveToIdle_DMA(&huart5, uart5_rx_buffer, sizeof(uart5_rx_buffer));  // 启动DMA接收
        __HAL_DMA_DISABLE_IT(huart5.hdmarx, DMA_IT_HT);                                   // 关闭DMA接收缓冲区溢出中断
    }
    // 传入雷达回调函数判断
    BSP_LEADAR_UARTEx_RxEventCallback(huart, Size);
}

// 重定向printf到UART,方便调试 uart3 左typec uart4 蓝牙
int _write(int file, char* ptr, int len) {
    HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, HAL_MAX_DELAY);
    return len;
}